
namespace Stee.CAP8.MessageBus.Kafka.Configurations
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Configuration for Kafka admin client
    /// See below reference for detailed documentation on indivdual configurations
    /// https://docs.confluent.io/current/installation/configuration/admin-configs.html
    /// </summary>
    public class AdminConfiguration
    {
        #region Properties

        /// <summary>
        /// Gets the initial bootstrap servers' addresses as a CSV list of broker host or host:port.
        /// Mandatory configuration.
        /// </summary>
        public string BootstrapServers { get; private set; } = string.Empty;

        /// <summary>
        /// Gets the validity of admin configuration
        /// </summary>
        public bool IsValid
        {
            get { return this.Validate(); }
        }

        #endregion Properties


        #region Constructor & Initializers

        /// <summary>
        /// Initializes a new instance of the AdminConfigurations class
        /// </summary>
        /// <param name="bootstrapServers">Bootstrap servers' addresses as a CSV list</param>
        public AdminConfiguration(string bootstrapServers)
        {
            bootstrapServers = bootstrapServers?.Trim();

            if (string.IsNullOrEmpty(bootstrapServers))
            {
                throw new ArgumentNullException(nameof(bootstrapServers));
            }

            this.BootstrapServers = bootstrapServers;
        }

        /// <summary>
        /// Initializes a new instance of the AdminConfigurations class.
        /// Make certain that all cases of dictionary keys matches that of the respective class properties.
        /// </summary>
        /// <param name="configurations">Configuration mappings to property name. Eg: "BootstrapServers" => "127.0.0.1:9092"</param>
        public AdminConfiguration(Dictionary<string, string> configurations)
        {
            if (configurations == null)
            {
                throw new ArgumentNullException($"Configuration is null: {nameof(configurations)}");
            }
            else if (!configurations.ContainsKey(nameof(this.BootstrapServers)))
            {
                throw new ArgumentNullException($"Mandatory configuration is null: {nameof(this.BootstrapServers)}");
            }

            //// Check mandatory configurations
            string bootstrapServers = configurations[nameof(this.BootstrapServers)];

            if (string.IsNullOrEmpty(bootstrapServers))
            {
                throw new ArgumentNullException($"Mandatory configuration is empty: {nameof(this.BootstrapServers)}");
            }

            this.InitializeProperties(configurations);
        }

        /// <summary>
        /// Initializes the configuration mappings into properties
        /// </summary>
        /// <param name="configurations">Configuration mappings to property name. Eg: "BootstrapServers" => "127.0.0.1:9092"</param>
        private void InitializeProperties(Dictionary<string, string> configurations)
        {
            foreach (KeyValuePair<string, string> item in configurations)
            {
                switch (item.Key)
                {
                    case nameof(this.BootstrapServers):
                        this.BootstrapServers = item.Value?.Trim();
                        break;

                    default:
                        //// TODO: log invalid property
                        break;
                }
            }
        }

        #endregion Constructor & Initializers


        #region Private Methods

        /// <summary>
        /// Validate admin configurations
        /// </summary>
        /// <returns>Return TRUE if configuration is valid else FALSE</returns>
        private bool Validate()
        {
            bool isValid = true;

            if (string.IsNullOrEmpty(this.BootstrapServers))
            {
                isValid = false;
            }

            return isValid;
        }

        #endregion Private Methods
    }
}
